import type {
  LocationQueryRaw,
  NavigationGuardNext,
  RouteLocationNormalized,
  RouteLocationRaw,
  Router
} from 'vue-router';
import type { RouteKey, RoutePath } from '@elegant-router/types';
import { useAuthStore } from '@/store/modules/auth';
import { useRouteStore } from '@/store/modules/route';
import { localStg } from '@/utils/storage';
import { getRouteName } from '@/router/elegant/transform';

// 检查是否已登录
function isLoggedIn() {
  return Boolean(localStg.get('token'));
}

// 检查是否需要登录
function needLogin(to: RouteLocationNormalized) {
  return !to.meta.constant;
}

// 检查是否有访问权限
function hasAccessPermission(to: RouteLocationNormalized) {
  const authStore = useAuthStore();
  const routeRoles = to.meta.roles || [];
  const hasRole = authStore.userInfo.roles.some(role => routeRoles.includes(role));
  return authStore.isStaticSuper || !routeRoles.length || hasRole;
}

/**
 * 创建路由守卫
 *
 * @param router - Vue Router 实例
 */
export function createRouteGuard(router: Router) {
  router.beforeEach(async (to, from, next) => {
    const redirect = await initRoute(to);
    if (redirect) return next(redirect);

    const isLogin = isLoggedIn();
    const needToLogin = needLogin(to);

    // 已登录时访问登录页，跳转到首页
    if (to.name === 'login' && isLogin) return next({ name: 'root' });

    // 不需要登录的页面直接放行
    if (!needToLogin) return handleRouteSwitch(to, from, next);

    // 需要登录但未登录，跳转到登录页
    if (!isLogin) {
      return next({
        name: 'login',
        query: { redirect: to.fullPath }
      });
    }

    // 已登录但无权限，跳转到403页
    if (!hasAccessPermission(to)) return next({ name: '403' });

    // 正常放行
    handleRouteSwitch(to, from, next);
  });
}

/**
 * 初始化路由
 *
 * @param to - 目标路由
 * @returns 需要重定向的路由地址，无需重定向返回null
 */
async function initRoute(to: RouteLocationNormalized): Promise<RouteLocationRaw | null> {
  const routeStore = useRouteStore();
  const isNotFound = to.name === 'not-found';
  const isLogin = isLoggedIn();

  // 初始化常量路由
  if (!routeStore.isInitConstantRoute) {
    await routeStore.initConstantRoute();
    return {
      path: to.fullPath,
      replace: true,
      query: to.query,
      hash: to.hash
    };
  }

  // 未登录情况处理
  if (!isLogin) {
    if (to.meta.constant && !isNotFound) {
      routeStore.onRouteSwitchWhenNotLoggedIn();
      return null;
    }
    return {
      name: 'login',
      query: getLoginRedirectQuery(to, routeStore.routeHome)
    };
  }

  // 初始化动态路由
  if (!routeStore.isInitAuthRoute) {
    await routeStore.initAuthRoute();
    if (isNotFound) {
      const path = to.redirectedFrom?.name === 'root' ? '/' : to.fullPath;
      return { path, replace: true, query: to.query, hash: to.hash };
    }
  }

  routeStore.onRouteSwitchWhenLoggedIn();

  // 检查是否是有效但无权限的路由
  if (isNotFound && (await routeStore.getIsAuthRouteExist(to.path as RoutePath))) {
    return { name: '403' };
  }

  return null;
}

/**
 * 处理路由切换
 *
 * 主要处理外链跳转等情况
 */
function handleRouteSwitch(to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext) {
  // 处理外链跳转
  if (to.meta.href) {
    window.open(to.meta.href, '_blank');
    next({ path: from.fullPath, replace: true, query: from.query, hash: to.hash });
    return;
  }
  next();
}

/** 获取登录页的重定向查询参数 */
function getLoginRedirectQuery(to: RouteLocationNormalized, homeRoute: RouteKey): LocationQueryRaw {
  const redirect = to.fullPath;
  const [path, query] = redirect.split('?');
  const routeName = getRouteName(path as RoutePath);

  // 如果重定向到首页且有查询参数，特殊处理
  if (homeRoute === routeName && query) {
    return { redirect: `/?${query}` };
  }

  // 非登录页且非首页才添加redirect参数
  return to.name !== 'login' && homeRoute !== routeName ? { redirect } : {};
}
